// 1. 创建一个axios实例 (baseURL, timeOut)
// 2. 配置实例的请求拦截器 (请求头携带token)
// 3. 配置实例的响应拦截器 (把数据解构一层, 请求成功但业务失败<status:200, code不为10000>, 401错误)
// 3.1 把数据解构一层
// 3.2 请求成功但业务失败<status:200, code不为10000>
// 提示错误, 抛出一个错误
// 3.3 401错误 提示, 删除用户信息, 回到登录页
// (由哪个页面去登录页的,登录成功就回到该页面, 如果没有则回首页)
import router from '@/router'
import axios, { type Method } from 'axios'

import { Toast } from 'vant'
import { useUserStore } from './../stores/modules/user'

// 1. 创建一个axios实例 (baseURL, timeOut)
const baseURL = 'https://consult-api.itheima.net'
const instance = axios.create({
  baseURL,
  timeout: 10000
})

// 2. 配置实例的请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 2.1 携带token
    const store = useUserStore()
    if (store.user?.token && config.headers) {
      config.headers['Authorization'] = `Bearer ${store.user?.token}`
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 3. 配置实例的响应拦截器
instance.interceptors.response.use(
  (res) => {
    // 3.1 请求成功但业务失败(code不为10000)
    if (res.data.code !== 10000) {
      Toast(res.data.message)
      // 3.2 给外部抛出错误
      return Promise.reject(res.data)
    }
    return res.data
  },
  (error) => {
    // 3.3 处理401错误
    if (error.response.status === 401) {
      // 提示
      Toast('token异常, 请重新登录')
      // 删除用户信息
      const store = useUserStore()
      store.delUser()
      // 回到登录页
      // /home?abc=11&cc=2
      // path -->  /home
      // fullPath ---> /home?abc=11&cc=2
      router.push(`/login?returnUrl=${router.currentRoute.value.fullPath}`)
    }
    return Promise.reject(error)
  }
)

// 4. 请求工具函数
type Data<T> = {
  code: number
  message: string
  data: T
}

const request = <T>(
  url: string,
  method: Method = 'get',
  submitData?: object
) => {
  return instance.request<T, Data<T>>({
    url,
    method,
    // get请求: params: {}, 其它请求: data: {}
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}

export { instance, baseURL, request }
